package cn.song.docflow.controller;

import cn.song.docflow.common.R;
import cn.song.docflow.model.dto.TemplateInformationDTO;
import cn.song.docflow.service.DocumentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.io.File;

import java.net.URLEncoder;

/**
 * 文档控制器
 *
 * @author SongRenShuo
 * @date 2023/05/20
 */
@Slf4j
@Validated
@RestController
@RequestMapping("/api/document")
public class DocumentController {

    @Autowired
    private DocumentService documentService;

   /**
     * 基础URL
     */
    @Value("${baseUrl:http://localhost:58080}")
    private String baseUrl;


    /**
     * 生成文档
     *
     * @param templateInfo 模板信息
     * @return 返回对象
     */
    @PostMapping("/generate-document")
    public R<String> generateDocument(@RequestBody @Valid TemplateInformationDTO templateInfo) {
        try {
            log.info("生成文档请求: {}", templateInfo);

            String filePath;
            if (templateInfo.getFileType() == 1) {
                // 生成Word文档
                filePath = documentService.generateWord(templateInfo);
            } else if (templateInfo.getFileType() == 2) {
                // 生成PDF文档
                filePath = documentService.generatePdf(templateInfo);
            } else {
                return R.failed(400,"不支持的文件类型",String.valueOf(templateInfo.getFileType()));
            }

            // 将绝对路径转换为相对路径
            String relativePath = getRelativeFilePath(filePath);
            return R.success( "文档生成成功",relativePath);
        } catch (Exception e) {
            log.error("生成文档失败: {}", e.getMessage(),e);
            return R.failed("生成文档失败: " + e.getMessage());
        }
    }



    /**
     * 将绝对路径转换为可访问的完整URL
     *
     * @param absolutePath 绝对路径
     * @return 可访问的文件URL
     */
    private String getRelativeFilePath(String absolutePath) {
        try {
            // 安全地提取文件名 - 从根本上避免路径遍历问题
            String fileName = extractFileName(absolutePath);

            // 返回以http开头的完整URL
            return baseUrl +
                    "/exports/" +
                    URLEncoder.encode(fileName, "UTF-8");
        } catch (Exception e) {
            log.error("生成文件URL失败: {}", e.getMessage(),e);
            throw new RuntimeException("生成文件URL失败", e);
        }
    }

    /**
     * 安全地从文件路径中提取文件名
     * 从根本上避免路径遍历问题，不使用File对象
     */
    public static String extractFileName(String filePath) {
        if (filePath == null || filePath.isEmpty()) {
            throw new IllegalArgumentException("文件路径不能为空");
        }

        // 使用字符串操作安全地提取文件名，避免使用File对象带来的安全隐患
        int lastSeparatorIndex = filePath.lastIndexOf(File.separatorChar);
        int lastAltSeparatorIndex = filePath.lastIndexOf('/');

        // 取两种分隔符中最后出现的位置
        int lastIndex = Math.max(lastSeparatorIndex, lastAltSeparatorIndex);

        // 如果没有找到分隔符，则整个字符串就是文件名
        return (lastIndex == -1) ? filePath : filePath.substring(lastIndex + 1);
    }
}
